package com.wiscamp.ninechapters.problems.adapter.resources.sets;

import com.wiscamp.ninechapters.problems.application.dto.commands.CreateProblemSetCommand;
import com.wiscamp.ninechapters.problems.application.dto.commands.sets.*;
import com.wiscamp.ninechapters.problems.application.dto.vo.problems.ProblemVO;
import com.wiscamp.ninechapters.problems.application.dto.vo.sets.ProblemSetVO;
import com.wiscamp.ninechapters.problems.application.services.ProblemSetAppService;
import cube.ddd.adapter.BaseController;
import cube.ddd.adapter.RestResponse;
import cube.ddd.application.command.DeleteCommand;
import cube.ddd.aspect.HandleResourceException;
import cube.ddd.common.query.PagedQuery;
import cube.ddd.utils.ResourceUtils;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.ws.rs.PathParam;
import jakarta.ws.rs.core.Context;
import org.springframework.web.bind.annotation.*;

import java.util.Collection;

/**
 * 习题集服务端点
 *
 * @author yifeng
 */
@RestController
@RequestMapping("/api/Problems")

@Tag(name = "题库-习题集信息")
public class ProblemSetController extends BaseController {

    private final ProblemSetAppService problemSetAppService;

    public ProblemSetController(ProblemSetAppService problemSetAppService) {
        this.problemSetAppService = problemSetAppService;
    }

    /**
     * 通过习题集编号获取习题集
     *
     * @param request
     * @param response
     * @param setId
     * @return
     */
    @GetMapping("ProblemSets/{setId}")
    @Operation(summary = "通过习题集编号获取习题集")
    @HandleResourceException
    public RestResponse<ProblemSetVO> getSet(@Context HttpServletRequest request, @Context HttpServletResponse response,
                                             @PathVariable("setId") long setId) {
        return ResourceUtils.getById(request, response, setId, problemSetAppService::getProblemSet);
    }

    /**
     * 通过机构编号和习题集代码获取习题集
     *
     * @param setCode
     * @return
     */
    @GetMapping("Organizations/{organizationId}/ProblemSets/Code/{setCode}")
    @Operation(summary = "通过机构编号和习题集代码获取习题集")
    @HandleResourceException
    public RestResponse<ProblemSetVO> getSetByCode(@Context HttpServletRequest request,
                                                   @Context HttpServletResponse response,
                                                   @PathVariable("organizationId") long organizationId,
                                                   @PathVariable("setCode") String setCode) {
        return ResourceUtils.getByTextAndId(request, response, setCode, organizationId,
                problemSetAppService::getProblemSetByCode);
    }

    /**
     * 通过机构编号和习题集名称获取习题集列表
     *
     * @param setName
     * @return
     */
    @GetMapping("organizations/{organizationId}/problemSets/name/{setName}")
    @Operation(summary = "通过机构编号和习题集名称获取习题集列表")
    @HandleResourceException
    public RestResponse<Collection<ProblemSetVO>> getSetsByName(@Context HttpServletRequest request, @Context HttpServletResponse response,
                                                                @PathVariable("organizationId") long organizationId,
                                                                @PathVariable("setName") String setName) {
        return ResourceUtils.getListByTextAndId(request, response, setName, organizationId,
                problemSetAppService::getProblemSetsByName);
    }

    /**
     * 通过机构编号获取习题集列表
     *
     * @param organizationId
     * @return 习题集列表
     */
    @GetMapping("Organizations/{organizationId}/ProblemSets")
    @Operation(summary = "通过机构编号获取习题集列表")
    @HandleResourceException
    public RestResponse<Collection<ProblemSetVO>> getProblemSetsByOrganization(@Context HttpServletRequest request, @Context HttpServletResponse response,
                                                                               @PathVariable("organizationId") long organizationId) {
        return ResourceUtils.getListById(request, response, organizationId,
                problemSetAppService::getProblemSetsByOrganization);
    }

    @GetMapping("ProblemSets/Action/Copy")
    @Operation(summary = "通过习题集编号复制习题集")
    @HandleResourceException
    public RestResponse<ProblemSetVO> copyProblemSet(@Context HttpServletRequest request, @Context HttpServletResponse response,
                                                     @RequestBody CopyProblemSetCommand command) {
        var newSet = problemSetAppService.copyProblemSet(command);
        return ResourceUtils.getOkResponse(request, response, newSet);
    }

    @GetMapping("ProblemSets/{setId}/Tex")
    @Operation(summary = "通过习题集编号获取习题集的tex文件压缩包地址")
    @HandleResourceException
    public RestResponse<String> getSetTexById(@Context HttpServletRequest request, @Context HttpServletResponse response,
                                              @PathVariable("setId") long setId) {
        var result = problemSetAppService.exportProblemSet(setId);
        return ResourceUtils.getOkResponse(request, response, result);
    }

    @PutMapping("ProblemSets/{setId}/Actions/ChangeName/{name}")
    @Operation(summary = "通过机构编号改变习题集名称")
    @HandleResourceException
    public RestResponse<Boolean> changeProblemSetName(@Context HttpServletRequest request, @Context HttpServletResponse response,
                                                      @RequestBody ChangeProblemSetNameCommand command) {
        var success = problemSetAppService.changeProblemSetName(command);
        return ResourceUtils.getOkResponse(request, response, success);
    }

    /**
     * 通过习题集编号删除习题集
     *
     * @param id
     * @return
     */
    @PutMapping("ProblemSets/Actions/Delete")
    @Operation(summary = "通过习题集编号删除习题集")
    @HandleResourceException
    public RestResponse<Boolean> deleteProblemSet(@Context HttpServletRequest request, @Context HttpServletResponse response,
                                                  @RequestBody DeleteCommand command) {
        return ResourceUtils.delete(request, response, command, problemSetAppService::deleteProblemSet);
    }

    @DeleteMapping("ProblemSets/{setId}")
    @Operation(summary = "通过习题集编号删除习题集")
    @HandleResourceException
    public RestResponse<Boolean> deleteProblemSetById(@Context HttpServletRequest request, @Context HttpServletResponse response,
                                                  @PathVariable("setId") long setId) {
        var command = new DeleteCommand();
        command.setId(setId);
        return ResourceUtils.delete(request, response, command, problemSetAppService::deleteProblemSet);
    }

    /**
     * 创建习题集
     *
     * @param command
     * @return
     */
    @PostMapping("ProblemSets")
    @Operation(summary = "创建习题集")
    @HandleResourceException
    public RestResponse<ProblemSetVO> createProblemSet(@Context HttpServletRequest request, @Context HttpServletResponse response,
                                                       @RequestBody CreateProblemSetCommand command) {
        return ResourceUtils.createOrUpdate(request, response, command, problemSetAppService::createProblemSet);
    }

    /**
     * 更新习题集
     *
     * @param command
     * @return
     */
    @PutMapping("ProblemSets")
    @Operation(summary = "更新习题集")
    @HandleResourceException
    public RestResponse<ProblemSetVO> updateProblemSet(@Context HttpServletRequest request, @Context HttpServletResponse response,
                                                       @RequestBody UpdateProblemSetCommand command) {
        return ResourceUtils.createOrUpdate(request, response, command, problemSetAppService::updateProblemSet);
    }


    @DeleteMapping("ProblemSets/Actions/Remove/Problem")
    @Operation(summary = "从习题集中移除某道题")
    @HandleResourceException
    public RestResponse<Boolean> removeSetProblem(@Context HttpServletRequest request, @Context HttpServletResponse response,
                                                  @RequestBody RemoveSetProblemCommand command) {
        var result = problemSetAppService.removeSetProblem(command);
        return ResourceUtils.getOkResponse(request, response, result);
    }

    @DeleteMapping("ProblemSets/{setId}/Actions/Remove/Problem/{problemId}")
    @Operation(summary = "从习题集中移除某道题")
    @HandleResourceException
    public RestResponse<Boolean> removeSetProblem(@Context HttpServletRequest request, @Context HttpServletResponse response,
                                                  @PathVariable("setId") long setId,
                                                  @PathVariable("problemId") long problemId) {
        var command = new RemoveSetProblemCommand();
        command.setSetId(setId);
        command.setProblemId(problemId);
        var result = problemSetAppService.removeSetProblem(command);
        return ResourceUtils.getOkResponse(request, response, result);
    }

    /**
     * 分页获取习题集列表
     *
     * @return 习题集列表
     */
    @PostMapping("ProblemSets/Query")
    @Operation(summary = "分页获取习题集列表")
    @HandleResourceException
    public RestResponse<Collection<ProblemSetVO>> getProblemSetsByQuery(@Context HttpServletRequest request, @Context HttpServletResponse response,
                                                                        @RequestBody PagedQuery query) {
        return ResourceUtils.getPagedObjectsByQuery(request, response, query, problemSetAppService::getProblemSetsByQuery);
    }

    /**
     * 通过题集代码创建习题集
     *
     * @param userId
     * @param poolCode
     * @return
     */
    /*@PostMapping("ProblemSets/Actions/Create/By/Collection")
    @Operation(summary = "通过题集代码创建习题集")
    @HandleResourceException
    public RestResponse<Long> createProblemSetByCollection(@Context HttpServletRequest request, @Context HttpServletResponse response,
                                                           @RequestBody CreateProblemSetByCollectionCommand command) {
        var set = problemSetAppService.createProblemSetByCollection(command);
        return ResourceUtils.getOkResponse(request, response, set.getSetId());
    }*/

    @PostMapping("ProblemSets/Actions/Create/By/Collection")
    @Operation(summary = "通过题集代码创建习题集")
    @HandleResourceException
    public RestResponse<Long> createProblemSetByCollection(@Context HttpServletRequest request, @Context HttpServletResponse response,
                                                           @PathParam("collectionCode") String collectionCode) {
        var command = new CreateProblemSetByCollectionCommand();
        command.setOrganizationId(1);
        command.setCollectionCode(collectionCode);
        var set = problemSetAppService.createProblemSetByCollection(command);
        return ResourceUtils.getOkResponse(request, response, set.getSetId());
    }

    /**
     * @param request
     * @param response
     * @return
     */
    @PostMapping("/ProblemSets/Actions/Create/By/Rule")
    @Operation(summary = "通过规则编号创建习题集")
    @HandleResourceException
    public RestResponse<ProblemSetVO> createProblemSetByRule(@Context HttpServletRequest request, @Context HttpServletResponse response,
                                                             @RequestBody CreateProblemSetByRuleCommand command) {
        var set = problemSetAppService.createProblemSetByRule(command);
        return ResourceUtils.getOkResponse(request, response, set);
    }

    /**
     * @param request
     * @param response
     * @return
     */
    @PostMapping("/ProblemSets/Actions/Create/By/CustomText")
    @Operation(summary = "通过定制文本创建习题集")
    @HandleResourceException
    public RestResponse<ProblemSetVO> createProblemSetByCustomText(@Context HttpServletRequest request, @Context HttpServletResponse response,
                                                                   @RequestBody CreateProblemSetByCustomTextCommand command) {
        var set = problemSetAppService.createProblemSetByCustomText(command);
        return ResourceUtils.getOkResponse(request, response, set);
    }

    @PostMapping("ProblemSets/Actions/CreateOrAdd")
    @Operation(summary = "通过选中的题目创建习题集")
    @HandleResourceException
    public RestResponse<ProblemSetVO> createOrAddToProblemSetByProblems(@Context HttpServletRequest request, @Context HttpServletResponse response,
                                                                       @RequestBody CreateOrAddToProblemSetCommand command) {
        var set = problemSetAppService.createOrAddToProblemSetByProblems(command);
        return ResourceUtils.getOkResponse(request, response, set);
    }

    /*@PostMapping("Problems/Actions/CustomQuery")
    @Operation(summary = "通过定制标签和知识点查询题目")
    @HandleResourceException
    public RestResponse<Collection<ProblemVO>> getProblemsByCustomQuery(@Context HttpServletRequest request,
                                                                        @Context HttpServletResponse response, @PathVariable("organizationId") long organizationId,
                                                                        CustomProblemQuery query) {
        var problems = problemSetAppService.getProblemsByCustomQuery(query);
        return ResourceUtils.getOkResponse(request, response, problems);
    }*/

    @GetMapping("ProblemSets/{setId}/Problems")
    @Operation(summary = "通过习题集编号获取题列表")
    @HandleResourceException
    public RestResponse<Collection<ProblemVO>> getProblemsBySet(@Context HttpServletRequest request, @Context HttpServletResponse response,
                                                                @PathVariable("setId") long setId) {
        return ResourceUtils.getListById(request, response, setId, problemSetAppService::getProblemsBySet);
    }
}
